/**********************************************************
                   clam.c

Routines and interface for Contig Analysis.
Calls routines in next.c.

fpp variables: 
showburied, clhigh, root, trail, fileName, merging, centre_pos

clone.match is parent name, ' ' is no parent
clone.parent is parent index
clone.mattype is PARENT, APPROX, EXACT

Sz.match is number of matching bands
Sz.parent is clone.match
**************************************************************/
#include <stdio.h>
#include <pwd.h>
#include <malloc.h>
#include "clam.h"
#include "../fpp/types.h"
#include <gtk/gtkwidget.h>

extern BOOL ZboolCpM();
extern void quitCpM(), ZautoCpM(), show_help();
extern void CpMdisplay();
extern void calcDistribution();
extern int Zcnt_shared_markers(struct tmpCz*, struct tmpCz* ,struct tmpSz*);
extern int ZscoreCpM(struct tmpCz*,struct tmpCz*, struct tmpSz*);
extern int loadCzfast();
extern int Zbcm();
extern void refresh_all_track_colors();
extern void gtk_select_colored();
             /** fpp functions **/
extern void displaymess(), recalccontigs(), highlightnodraw(), point2();
extern void clearall(), redrawfingerprints(), move_selected();
extern void removespaces();
extern void c_update_fields();
extern void b_update_fields();
extern void ZselectMTP(); 

extern int g92, g9a, g9b, g9c, gMTP;
extern int loadSizeCz();
extern void clear_Zunc(), Out_ends();
extern void Zsparse_zap(), Zexpert_zap(), Zfp_zap(), Zgel_zap();
extern void getdatehead(), quitCB(), set_Zunc();
extern void Zcalc_zap(), Zbuild_zap(), Zsel_zap();
extern void initZbury(), quitZap(), quitClam2(), Zrule_menu(), okAllMenu();
extern int loadCz(), Zgetdiff();
extern void  Z_OneCtg(), Z_OneNext(),Z_OneAgain(), Z_OneAdd(), Z_OneBury();
extern void Z_BurCtg(), Z_BurNext(),Z_BurAgain(), Z_BurAdd();
extern void Zsel_bury();
extern void  Zall_unbury(), Z_removeStop(), Z_buryStop(), Z_unburyStop();
extern void Z_undoInc();
extern int Bzn, Gzn, Zprtype;
extern GtkWidget *ctg_window;

char scoreText[100], set1Text[CLONE_SZ+20], set2Text[CLONE_SZ+20];
int removeBox, incBox, compareBox, findburyBox, unburyallBox, buryBox, unburyBox;
int Zall_ok();
void  ZhighP(), Set1(), scanClamA(), scanClamB(), scanClamC(), ZhighCin(), ZclearHigh(), Select_and_Colour();
char endText[14], oldctgText[14];
char tolText[14], cutText[14], uncText[14], burText[14], bestText[14];
static char badText[14];

#define BadOlap(olap, m) (abs(olap - m) > Pz.diffInt)

#define Show {if (graphActivate(g9a)){graphPop(); graphRedraw();} \
              if (graphActivate(g9b)){graphPop(); graphRedraw();} \
              if (graphActivate(g9c)){graphPop(); graphRedraw();}}
#define Output {if (Pz.logFlag) {fprintf(Zlogfp,"%s",ZBuf); fflush(Zlogfp);} if (Pz.stdFlag) {printf("%s",ZBuf); fflush(stdout);}}

static void pickg9A(), pickg9B(), pickg9C(), hitCR();
static void EvalC1z(), C1zDb(), C1zCtg(), EvalCtg();
static void Set2(), SetMatch();
void ShowIncr();  /* cari 4aug04 */
static void SelectColoured(), EvalMark();
static void  calc_olap(), C1zMark();
static void CtgEnds(), SelEnds(), CtgCheck(), CtgStep(), NoStep(), BadCtg();
static void MultCtg(), OneClone(), SplitMarker(), FindOrphans();
/* sness */
void snCtgCheck(), snCtgStep();

static int useCpMArc, useSzArc, logArc, stdArc, set1Box, set2Box;
static int markclFlag=0, markctgFlag=0,  marksplitFlag=1;
static int buryselBox, endBox, scoreBox, badBox, tolBox, 
           cutBox, burBox, bestBox; 

static char hidestate[3][20] = {"AllClone", "NoBuried", "NoPseudo"};

static void type0() { Zrule_menu(1);}
static char msg[256];

static struct contig *Nostep=NULL, *Ctgstep=NULL;

void scanClam() {scanClamA(); scanClamB(); scanClamC();}

extern char* ZBufPrint;
extern char* ZBufPtr;
extern int ZBufSize;

/***************************************************************
                      help 
****************************************************************/
static void zhelpA()
{
show_help("Contig/Analysis/Evaluate","evaluate");
}
static void zhelpB()
{
show_help("Contig/Analysis/Compute CBmap","ctgCBmap");
}
static void zhelpC()
{
show_help("Contig/Analysis/Semi-edit","semiedit");
}
static void zhelp()
{
show_help("Parameters","parameters");
}
/****************************************************************
                      DEF: findOldctg
*****************************************************************/
void findOldctg()
{
CLONE *clp;
struct contig *p;
int cnt=0, oldctg;

  ZclearHigh();
  sscanf(oldctgText, "%d", &oldctg);
  for (p=root; p!=NULL; p = p->new)
  {
     clp = arrp(acedata,p->next, CLONE);
     if (clp->oldctg==oldctg) {cnt++; ZhighP(CLAM,p);}
  }
  printf("Oldctg %d has %d clones\n",oldctg, cnt);
  refresh_all_track_colors();
}

/**************************************************************
                      DEF: ClamShare
Any shared variables, this is called.
****************************************************************/
void ClamShare(int type)
{
  NoPop=1;
  if (type!=4) ClamCtgDisplay2();
  if (type!=1) EvalCtgDisplay();
  if (type!=2) CBCtgDisplay();
  if (type!=3) EditCtgDisplay();
  if(graphActivate(gMTP)) ZselectMTP();
  NoPop=0;
  set_Zunc();
}
/******************************************************************/
int fppFindClone(char *name, int *index)
{
   return fppFind(acedata,name,index, cloneOrder);
}
                    
/******************************************************************/
void Zopenlog()
{
struct passwd *uinfo;
char buf[200];

    if (Zlogfp != NULL) return;

    uinfo = (struct passwd *) getpwuid((uid_t) geteuid());
    if (uinfo== NULL) buf[0]='0';
    else sprintf(buf, "%s.", uinfo->pw_name);

    if(strlen(dirName)>0){
      if((Zlogfp = fopen(messprintf("%s/%s.%slog", 
                  dirName, fileName, buf),"a")) == NULL ){
        displaymess("Cannot open the log file.");
	return; 
      }
    }
    else{
      if((Zlogfp = fopen(messprintf("%s.%slog", fileName, buf),"a")) == NULL ){
        displaymess("Cannot open the log file.");
	return; 
      }
    }
    getdatehead(buf);
    fprintf(Zlogfp,"\nFPC v%s\n", buf); 
}
/****************************************************************
                    DEF: quitClamA();
*****************************************************************/
void quitClamA()
{
   if (graphActivate(g9a)) {
       graphDestroy();
       if (graphActivate(grule)) graphDestroy();
       quitCpM();
   }
}
/****************************************************************
                    DEF: quitClamB();
*****************************************************************/
void quitClamB()
{
   if (graphActivate(g9b)) {
       graphDestroy();
       if (graphActivate(grule)) graphDestroy();
       quitCpM();
   }
}
/****************************************************************
                    DEF: quitClamC();
*****************************************************************/
void quitClamC()
{
   if (graphActivate(g9c)) {
       graphDestroy();
       if (graphActivate(grule)) graphDestroy();
   }
}
/************************************************************
                    DEF: showClam()
************************************************************/
void showClam()
{
   strncpy(scoreText,ZBuf, 100);
   Show;
}
/****************************************************************
                    DEF: ZhighP
Selected - lighblue, error - lightred, match green, clone1 - lightgray
****************************************************************/
void ZhighP(color, p)
int color;
struct contig *p; 
{
int color2;
CLONE *clp;
struct contig *q;

  if(ctg_window==NULL)
    return;
  if (arrp(acedata, p->next, CLONE)->selected &&
           color == LIGHTRED) color2 = RED;
  else color2=color;
  if (p!=clhigh) arrp(acedata, p->next, CLONE)->highcol = color2;

  if (color==CLAM && p->box==0 && showburied!=0) {
    clp = arrp(acedata, p->next, CLONE);
    if ((showburied==1 && clp->match[0]!=' ') ||
        (showburied==2 && clp->mattype == PSEUDO)) 
    {
          for (q=root; q!=NULL && q->next != clp->parent; q = q->new);
          if (q!=NULL) {
             if (arrp(acedata, q->next, CLONE)->highcol != CLAM &&
                 arrp(acedata, q->next, CLONE)->highcol != CLAM_CLONE) {
                if (q!=clhigh) arrp(acedata, q->next, CLONE)->highcol = CLAM_PARENT;
             }
          }
          return;
    }
  }
}
/****************************************************************
                    DEF: ZhighCin
****************************************************************/
void ZhighCin(color, cin)
{
struct contig *p;

  if(ctg_window==NULL)
    return;
  for (p=root; p!=NULL && p->next != cin; p = p->new);
  if (p==NULL) return;
     
  if (color==CLAM_CLONE && p==clhigh) return;
  ZhighP(color, p);
}
/****************************************************************
                    DEF: ZhighClp
****************************************************************/
void ZhighClp(color, clp)
int color;
CLONE *clp;
{
struct contig *p;

  if(ctg_window==NULL)
    return;
  for (p=root; p!=NULL && arrp(acedata, p->next, CLONE) != clp; p = p->new);
  if (p==NULL) return;
  ZhighP(color, p);
}
/****************************************************************
                      DEF: ZclearHigh
****************************************************************/
void ZclearHigh()
{
struct contig *p;
struct markerlist *mp;
struct marker *marker;
CLONE *clp;

  if(ctg_window==NULL)
    return;
  if (trail) return;

  for (p=root; p!=NULL; p = p->new) {
     clp = arrp(acedata, p->next, CLONE);
     if (clp->highcol != WHITE) {
       if (clp->selected) ZhighP(SELECTED, p);
       else ZhighP(WHITE, p);
       clp->highcol=WHITE;
     }
  }
  for(mp=markerlistroot; mp!=NULL; mp = mp->next){
      marker = arrp(markerdata,mp->markerindex,MARKER);
      if (marker->colour != 0 && marker->colour!=PCRCOLOUR) {
         if (marker->type!=markPCR) marker->colour = 0;
         else  marker->colour = PCRCOLOUR;
         if (marker->box != 0)
            graphBoxDraw(marker->box,BLACK, marker->colour);
      }
  }
}

/****************************************************************
                     DEF: SelectColoured
*****************************************************************/
static void SelectColoured()
{
  gtk_select_colored();  
}
/****************************************************************
                     DEF: ShowIncr
*****************************************************************/
void ShowIncr()
{
struct contig *p;
CLONE *cp;

  if(ctg_window==NULL)
     return;
  for(p=root; p!=NULL; p = p->new){
     cp = arrp(acedata, p->next, CLONE);
     if (cp->oldctg==0) ZhighP(DARKBLUE, p);
     else if (cp->ibc) ZhighP(CLAM_CLONE, p);
                /* cari 20feb04 MIDBLUE did not show */
     else if (cp->ctg!=cp->oldctg) ZhighP(VIOLET, p); 
  }
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                     DEF: Select_and_Colour
*****************************************************************/
void Select_and_Colour()
{
struct contig *p;
CLONE *cp;

  if(ctg_window==NULL)
    return;
  for(p=root; p!=NULL; p = p->new){
     cp = arrp(acedata, p->next, CLONE);
     if (showburied==1 && cp->match[0]!=' ') continue; 
     if (showburied==2 && cp->mattype == PSEUDO) continue; 
     if (cp->highcol != 0 && cp->highcol!=SELECTED && cp->selected) {
         cp->highcol = RED;
         if (p->box!=0) graphBoxDraw(p->box, BLACK, cp->highcol);
         if (p->chbox!=0) graphBoxDraw(p->chbox, BLACK, cp->highcol);
     } 
  }
}
/****************************************************************
                    DEF: Zall_ok
****************************************************************/
int Zall_ok(fp, type)
int fp, type;
{
  if (currentctg!=Sz.ctg) {
       if (type==1) EvalCtgDisplay();/* reinitialize things */
       if (type==2) CBCtgDisplay();/* reinitialize things */
       if (type==3) EditCtgDisplay();/* reinitialize things */
  }
  if (type==1) scanClamA();
  if (type==2) scanClamB();
  if (type==3) scanClamC();
  if(ctg_window==NULL)
    return 0;
  ZclearHigh();
  if (fp)
     if (!arrayExists(bands)) 
         if (fpRead() == -1) return 0;
return 1;
}
/****************************************************************
                    DEF: Zall_ok2
for routines comparing clone1 against contig
****************************************************************/
static int Zall_ok2()
{
  if (merging) 
  {
     if (C1z.ctg != mergecontig2 && C1z.ctg != mergecontig1)
     {
      sprintf(scoreText,"Clone %s not in contig %d or %d",set1Text,
                 mergecontig1, mergecontig2); Show;
      strcpy(ZBuf, scoreText); Output;
      return 0;
     }
  }
  else if (C1z.ctg != currentctg)
  {
      sprintf(scoreText,"Clone %s not in contig",set1Text); Show;
      strcpy(ZBuf, scoreText); Output;
      return 0;
  }
return 1;
}
/**************************************************************
                         header
**************************************************************/
static int header()
{
int row=1.0, width, col;

  sprintf(tolText,"%d",Pz.tol);
  sprintf(cutText,"%.0e",Pz.cutFlt);
  sprintf(burText,"%3.2f",Pz.burFlt);
  sprintf(badText,"%d", Pz.diffInt);
  sprintf(endText,"%d", Pz.fromendInt);
  sprintf(bestText,"%d",Pz.bestInt);
  Sz.ctg = currentctg;
  width=50.0;

    row = 1.0;
    graphText("Tolerance:",2,row);
    tolBox = graphTextEntry(tolText, 4, 13, row,hitCR);

    graphText("Cutoff:",18,row);
    cutBox = graphTextEntry(cutText, 6, 26, row,hitCR);

    graphText("Bury~:",33,row);
    burBox = graphTextEntry(burText, 5, 40, row,hitCR);

    row += 2.0;
    col=3.0;
    logArc = graphBoxStart();
      graphArc(col, row+0.5, 0.7, 0, 360); 
      if (Zlogfp!=NULL) Pz.logFlag=1;
      else Pz.logFlag=0;
      if (Pz.logFlag) graphFillArc(col, row+0.5, 0.4, 0, 360);
      graphBoxEnd();
      graphBoxDraw(logArc, BLACK, TRANSPARENT);
    graphText("Log",col+1,row);
    col+=6.0;
    stdArc = graphBoxStart();
      graphArc(col, row+0.5, 0.7, 0, 360); 
      if (Pz.stdFlag) graphFillArc(col, row+0.5, 0.4, 0, 360);
      graphBoxEnd();
      graphBoxDraw(stdArc, BLACK, TRANSPARENT);
    graphText("Stdout",col+1.0,row);

    col+=10.0;
    useCpMArc = graphBoxStart();
      graphArc(col, row+0.5, 0.7, 0, 360); 
      if (Cp.useFlag) graphFillArc(col, row+0.5, 0.4, 0, 360);
      graphBoxEnd();
      graphBoxDraw(useCpMArc, BLACK, TRANSPARENT);
    graphText("Use CpM",col+1.0,row);

    col+=9.0;
    graphButton("CpM Table",CpMdisplay,col,row);
    col+=12.0;
    graphButton("Help",zhelp,col,row);
    row += 2.0;
    scoreBox = graphBoxStart();
    graphTextPtr(scoreText,1.0,row,45);
    graphBoxEnd();
    graphBoxDraw(scoreBox,BLACK,CYAN);


    row += 2.0;
    graphLine(0.0,row,width,row);
    row += 1.0;
return row;
}
/*********************************************************
                  MAIN: EvalCtgDisplay
*********************************************************/
void EvalCtgDisplay()
{
float row;
float col, col1=2.0;
static MENUOPT amenu[] = { {quitClamA, "Close"},
    { graphPrint,"Print Screen"}, 
    { type0, "The Attic"},  
    { 0, 0 } };

  if (!arrayExists(bands)) 
      if (fpRead() == -1) {
          displaymess("No cor file - no analysis");
          return;
      }
  if(graphActivate(g9a)){   
    if (!NoPop) graphPop();
  }
  else if (NoPop) return;
  else{
                                             /* pos x, y; width, leng */
    g9a = graphCreate (TEXT_FIT,"Contig Evaluate",.2,.2,.427,.37); 
    graphRegister (PICK, pickg9A) ;
    scoreText[0] = '\0';
    set1Text[0] = '\0';
    set2Text[0] = '\0';
    if (Zlogfp==NULL && Pz.logFlag==1) Zopenlog();
    Nostep=Ctgstep=NULL;
  }
  graphClear();
  graphMenu(amenu);
  row = header();

    graphButton("Clone 1",Set1,col1,row);
    set1Box = graphTextEntry(set1Text, CLONE_SZ-1, 11.0, row, scanClamA);
    col=11.0+CLONE_SZ;
    graphButton("Eval",EvalC1z,col,row);
    col+=8.0;
    graphButton("--> Fpc",C1zDb,33.0,row);
    row += 1.5;
    if (Cp.useFlag>0) graphButton("--> Ctg CpM",C1zCtg,11.0,row);
    else graphButton("--> Ctg Prob",C1zCtg,11.0,row);
    col=11.0+CLONE_SZ;
    graphButton("--> Ctg Markers",C1zMark,col,row);
    row += 2.0;
    graphButton("Clone 2",Set2,col1,row);
    set2Box = graphTextEntry(set2Text, CLONE_SZ-1, 11.0, row,  scanClamA);
    col=11.0+CLONE_SZ;
    graphButton("--> Clone 1",SetMatch,col,row);
    col+=14.0;
    useSzArc = graphBoxStart();
        graphArc(col, row+0.5, 0.7, 0, 360); 
        if (Pz.useSz==1) graphFillArc(col, row+0.5, 0.4, 0, 360);
        graphBoxEnd();
        graphBoxDraw(useCpMArc, BLACK, TRANSPARENT);
    graphText("Size",col+1,row);

    row += 2.5;
    graphButton("Ctg --> Ends",CtgEnds,2.0,row);
    graphButton("Sel --> Ends",SelEnds,16,row);
    graphText("FromEnd:",31.0,row);
    endBox = graphTextEntry(endText, 4, 40, row,scanClamA);

    row += 2.5;
    graphButton("CtgCheck",CtgCheck,col1,row);
    graphButton("Step",CtgStep,11,row);
    graphButton("NoOlap",EvalCtg,17,row);
    graphButton("Step",NoStep,24,row);
    graphButton("BadOlap",BadCtg,31,row);
    badBox = graphTextEntry(badText, 4, 40.0, row,  scanClamA);

    row += 1.5;
    /* sness */
    graphButton("snCtgCheck",snCtgCheck,col1,row);
    graphButton("snCtgStep",snCtgStep,13.0,row);

    row += 1.5;
    graphButton("Marker Split",SplitMarker,col1,row);
    graphButton("MultCtg",MultCtg,17,row);
    graphButton("OneClone",OneClone,31,row);

  row += 2.5;
  graphButton("Close",quitClamA,2.0,row);
  graphButton("Help",zhelpA,10.0,row);
  row += 2.0;
  graphText("Some functions are F4 interruptable",2.0,row);
  cutBox = graphTextEntry(cutText,14,0,0,NULL);
  graphRedraw();
}

/*********************************************************
                  MAIN: CBCtgDisplay
*********************************************************/
void CBCtgDisplay()
{
float row;
float col1=2.0;
static MENUOPT amenu[] = { {quitClamB, "Close"},
    { graphPrint,"Print Screen"}, 
    { type0, "The Attic"},  
    { 0, 0 } };

  if (!arrayExists(bands)) 
      if (fpRead() == -1) {
          displaymess("No cor file - no analysis");
          return;
      }
  if(graphActivate(g9b)){   
    if (!NoPop) graphPop();
  }
  else if (NoPop) return;
  else{
                                             /* pos x, y; width, leng */
    g9b = graphCreate (TEXT_FIT,"Contig Compute CBmaps",.2,.2,.427,.24); 
    graphRegister (PICK, pickg9B) ;
    scoreText[0] = '\0';
    if (Zlogfp==NULL && Pz.logFlag==1) Zopenlog();
  }
  graphClear();
  graphMenu(amenu);
  row = header();

    graphText("Create CBmaps:",col1,row);
    graphButton("Calc",Zcalc_zap,col1+15.0,row);
    graphText("Best of",col1+25.0,row);
    bestBox = graphTextEntry(bestText, 5, col1+34.0, row,scanClamB);

    row += 1.5;
    graphText("A CBmap from:",col1,row);
    graphButton("Fp Order",Zfp_zap,col1+15.0,row);
    graphButton("Gel Order",Zgel_zap,col1+25,row);
    graphButton("Selected",Zsel_zap,col1+36,row);
    row += 1.5;
    graphText("Pick clones:",col1,row);
    graphButton("Build",Zbuild_zap,col1+15,row); 

  row += 2.0;
  graphButton("Close",quitClamB,2.0,row);
  graphButton("Help",zhelpB,10.0,row);
  graphButton("Unbury All",Zall_unbury,20.0,row);
  row += 2.0;
  graphText("All functions are F4 interruptable",2.0,row);

  cutBox = graphTextEntry(cutText,14,0,0,NULL);
  graphRedraw();
}

/*********************************************************
                  MAIN: EditCtgDisplay
*********************************************************/
void EditCtgDisplay()
{
float row;
float  col1=2.0;
static MENUOPT amenu[] = { {quitClamC, "Close"},
    { graphPrint,"Print Screen"}, 
    { type0, "The Attic"},  
    { 0, 0 } };

  if (!arrayExists(bands)) 
      if (fpRead() == -1) {
          displaymess("No cor file - no analysis");
          return;
      }
  if(graphActivate(g9c)){   
    if (!NoPop) graphPop();
    if (currentctg != Sz.ctg) 
         initZbury();
  }
  else if (NoPop) return;
  else{
                                             /* pos x, y; width, leng */
    g9c = graphCreate (TEXT_FIT,"Contig semi-auto edits",.2,.2,.427,.37); 
    graphRegister (PICK, pickg9C) ;
    scoreText[0] = '\0';
    oldctgText[0] = '\0';
    initZbury();
    if (Zlogfp==NULL && Pz.logFlag==1) Zopenlog();
  }
  graphClear();
  graphMenu(amenu);
  row = header();

    graphButton("SelectColored",SelectColoured, col1, row);
    graphButton("ShowAdditions", ShowIncr, 18, row);
    incBox = graphButton("UndoAdditions",Z_undoInc,33,row);
    row += 2.0;
    graphButton("Clear All",clearall, col1,row);
    graphText("Oldctg",18,row);
    graphTextEntry(oldctgText, 8, 25, row, findOldctg);
    graphButton("Orphans",FindOrphans, 37,row);
    row += 2.0;
    graphLine(0.0,row,50.0,row);
    row += 1.0;
    unburyallBox = graphButton("Unbury All",Zall_unbury,col1,row);
    removeBox = graphButton("Remove from Ctg",Z_removeStop,col1+13,row);
    buryselBox = graphButton("Bury selected",Zsel_bury,33,row);

    row += 1.5;
    unburyBox = graphButton("UnBury",Z_unburyStop,col1,row);
    buryBox = graphButton("Bury in:",Z_buryStop,col1+13,row);
    graphButton("Clone",Set1,col1+23,row);
    set1Box = graphTextEntry(set1Text, CLONE_SZ-1, 32.0, row, scanClamA);

    row += 2.0;
    findburyBox = graphButton("Find Canonicals",Z_BurCtg,col1,row);
    if (Bzn!=-1) graphBoxDraw(findburyBox, BLACK, LIGHTGRAY);
    graphButton("Next",Z_BurNext,col1+17.0,row);
    graphButton("Last",Z_BurAgain,col1+23,row);
    graphButton("Bury Purple",Z_BurAdd,col1+29,row);
  
    row += 2.0;
    strcpy(msg,"Compare KeySet");
    if (Gzn!=-1 && Zprtype==2) strcpy(msg,"Compare Singles");
    compareBox = graphButton(msg,Z_OneCtg,col1,row);
    if (Gzn!=-1) graphBoxDraw(compareBox, BLACK, LIGHTGRAY);

    graphButton("Next",Z_OneNext,col1+17.0,row);
    graphButton("Last",Z_OneAgain,col1+23,row);
    graphButton("Add",Z_OneAdd,col1+29,row);
    graphButton("Add&Bury",Z_OneBury,col1+34,row);

  row += 2.0;
  graphLine(0.0,row,50.0,row);
  row += 1.0;
  graphButton("Close",quitClamC,2.0,row);
  graphButton("Help",zhelpC,10.0,row);
  row += 2.0;
  graphText("Most functions are F4 interruptable",2.0,row);
  graphRedraw();
}

/*****************************************************************/
void scanClamA()
{
double tmp;
char buf[100];

  if(graphActivate(g9a)){   
    sscanf(tolText,"%d",&Pz.tol);
    sscanf(cutText,"%lf",&tmp);
    if (Pz.cutFlt!=tmp) {
         if (tmp>1.0) {
            sprintf(buf, "Cutoff %.0e cannot be greater than 1", tmp);
            graphMessage(buf);
            NoPop=1; EvalCtgDisplay(); NoPop=0;
            return;
         }
         Pz.cutFlt=tmp;
         ZautoCpM(1);
    }
    sscanf(burText,"%f",&Pz.burFlt);
    sscanf(badText,"%d", &Pz.diffInt);
    sscanf(endText,"%d", &Pz.fromendInt);
    ClamShare(1);
  }
}

/* cbmap */
void scanClamB()
{
double tmp;
char buf[100];

  if(graphActivate(g9b)){   
    sscanf(tolText,"%d",&Pz.tol);
    sscanf(cutText,"%lf",&tmp);
    if (Pz.cutFlt!=tmp) {
         if (tmp>1.0) {
            sprintf(buf, "Cutoff %.0e cannot be greater than 1", tmp);
            graphMessage(buf);
            NoPop=1; CBCtgDisplay(); NoPop=0;
            return;
         }
         Pz.cutFlt=tmp;
         ZautoCpM(1);
    }
    sscanf(burText,"%f",&Pz.burFlt);
    sscanf(bestText,"%d", &Pz.bestInt);
    ClamShare(2);
  }
}

void scanClamC()
{
double tmp;
char buf[100];

  if(graphActivate(g9c)){   
    sscanf(tolText,"%d",&Pz.tol);
    sscanf(cutText,"%lf",&tmp);
    if (Pz.cutFlt!=tmp) {
         if (tmp>1.0) {
            sprintf(buf, "Cutoff %.0e cannot be greater than 1", tmp);
            graphMessage(buf);
            NoPop=1; EditCtgDisplay(); NoPop=0;
            return;
         }
         Pz.cutFlt=tmp;
         ZautoCpM(1);
    }
    sscanf(burText,"%f",&Pz.burFlt);
    ClamShare(3);
  }
}

static void hitCR()
{
  scanClamA();
  scanClamB();
  scanClamC();
}

/* evaluate */
static void pickg9A(int box,double x,double y)
{
  if(box == tolBox) tolBox = graphTextEntry(tolText,14,0,0,NULL);
  else if(box == cutBox) cutBox = graphTextEntry(cutText,14,0,0,NULL);
  else if(box == burBox) burBox = graphTextEntry(burText,14,0,0,NULL);
  else if(box == badBox) badBox = graphTextEntry(badText,14,0,0,NULL);
  else if(box == set1Box)set1Box = graphTextEntry(set1Text,14,0,0,NULL);
  else if(box == set2Box)set2Box = graphTextEntry(set2Text,14,0,0,NULL);
  else if(box == endBox)endBox = graphTextEntry(endText,8,0,0,NULL);
  else if (box == useCpMArc) {
    Cp.useFlag = !Cp.useFlag;
    scanClamA();
    ZautoCpM();
    EvalCtgDisplay();
  }
  else if (box == useSzArc) {
    Pz.useSz = (!Pz.useSz);
    EvalCtgDisplay();
  }
  else if (box == logArc) {
    Pz.logFlag = (!Pz.logFlag);
    if (Pz.logFlag) Zopenlog();
    else if (Zlogfp!=NULL) {
       fclose(Zlogfp);
       Zlogfp=NULL;
    }
    EvalCtgDisplay();
  }
  else if (box == stdArc) {
    Pz.stdFlag = (!Pz.stdFlag);
    EvalCtgDisplay();
  }
  ClamShare(1);

  graphRedraw();
}

/* cbmap */
static void pickg9B(int box,double x,double y)
{
  if(box == tolBox) tolBox = graphTextEntry(tolText,14,0,0,NULL);
  else if(box == cutBox) cutBox = graphTextEntry(cutText,14,0,0,NULL);
  else if(box == burBox) burBox = graphTextEntry(burText,14,0,0,NULL);
  else if(box == bestBox) bestBox = graphTextEntry(bestText,14,0,0,NULL);
  else if (box == useCpMArc) {
    Cp.useFlag = !Cp.useFlag;
    scanClamB();
    ZautoCpM();
    CBCtgDisplay();
  }
  else if (box == logArc) {
    Pz.logFlag = (!Pz.logFlag);
    if (Pz.logFlag) Zopenlog();
    else if (Zlogfp!=NULL) {
       fclose(Zlogfp);
       Zlogfp=NULL;
    }
    CBCtgDisplay();
  }
  else if (box == stdArc) {
    Pz.stdFlag = (!Pz.stdFlag);
    CBCtgDisplay();
  }
  ClamShare(2);

  graphRedraw();
}

/* semi-auto */
static void pickg9C(int box,double x,double y)
{
  if(box == tolBox) tolBox = graphTextEntry(tolText,14,0,0,NULL);
  else if(box == cutBox) cutBox = graphTextEntry(cutText,14,0,0,NULL);
  else if(box == burBox) burBox = graphTextEntry(burText,14,0,0,NULL);
  else if (box == useCpMArc) {
    Cp.useFlag = !Cp.useFlag;
    scanClamC();
    ZautoCpM();
    EditCtgDisplay();
  }
  else if (box == logArc) {
    Pz.logFlag = (!Pz.logFlag);
    if (Pz.logFlag) Zopenlog();
    else if (Zlogfp!=NULL) {
       fclose(Zlogfp);
       Zlogfp=NULL;
    }
    EditCtgDisplay();
  }
  else if (box == stdArc) {
    Pz.stdFlag = (!Pz.stdFlag);
    EditCtgDisplay();
  }
  ClamShare(3);

  graphRedraw();
}

void Set1()
{
CLONE clp;
   if (clhigh==NULL && clonedisplayed == -1) return;
   if (clhigh!=NULL) clp = arr(acedata,clhigh->next, CLONE);
   else clp = arr(acedata,clonedisplayed, CLONE);
   strcpy(set1Text, clp.clone);
   if(graphActivate(g9a)) graphPop();
   graphRedraw();
}
static void Set2()
{
CLONE clp;
   if (clhigh==NULL && clonedisplayed == -1) return;
   if (clhigh!=NULL) clp = arr(acedata,clhigh->next, CLONE);
   else clp = arr(acedata,clonedisplayed, CLONE);
   strcpy(set2Text, clp.clone);
   if(graphActivate(g9a)) graphPop();
   graphRedraw();
}
/****************************************************************
                      DEF: EvalC1z
Comapre Clone 1 with all the clones is overlaps
****************************************************************/
static void EvalC1z()
{
int cntmark, index1, cnt=0, cnt_bad=0;
char ch, mk[5];
struct contig *p;

  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!Zall_ok(1,1)) return;
  if (!loadCz(&C1z, index1)) {
      sprintf(scoreText,"Cannot eval clone %s",set1Text); Show;
      strcpy(ZBuf, scoreText); Output;
      return;
  }
  if (!Zall_ok2()) return;
  ZhighCin(CLAM_CLONE, C1z.cin);

  if (Pz.logFlag || Pz.stdFlag) { 
     sprintf(ZBuf, 
          "\n>> Eval %s %db %s ctg%d (Tol %d Cutoff %.0e%s Bad Olap %d %s)\n",
         C1z.clone, C1z.nbands, C1z.btype,C1z.ctg,Pz.tol, Pz.cutFlt,
         CpMtype[Cp.useFlag], Pz.diffInt, hidestate[showburied]); 
     Output;
     sprintf(ZBuf,
       "      Clone  Coordinates Bands Olap Match Diff Prob Markers\n"); Output;
  }
  
  for (p=root; p!=NULL; p = p->new)
  {
     if (!loadCz(&C2z, p->next)) continue;
     if (showburied==1 && C2z.parent[0]!=' ') continue; 
     if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 

     if (strcmp(C1z.clone, C2z.clone)==0) {
         sprintf(ZBuf,
         "%12s (%4d,%4d) %3db ------------------------------ %12s  %s\n", 
             C1z.clone, C1z.left, C1z.right, 
             C1z.nbands, C1z.parent, C1z.btype);  Output;
         continue;
     }
     calc_olap();
     Zsulston(&C1z,&C2z,&Sz);
     if (Sz.olap == 0 && !ZboolCpM()) continue;
     cnt++;
     
     ch = ' ';
     if (BadOlap(Sz.olap, Sz.match)) ch='*';
     else if (ZboolCpM() && Sz.olap==0) ch='*'; 
     if (ch=='*') {
         cnt_bad++;
         ZhighP(LIGHTRED, p);
     }

     if (Pz.stdFlag || Pz.logFlag) { 
          cntmark = Zcnt_shared_markers(&C1z,&C2z,&Sz);
          if (Sz.mark > 0) sprintf(mk, "%2d", Sz.mark);
          else strcpy(mk,"  ");
          sprintf(ZBuf, 
           "%12s (%4d,%4d) %3db   %3d %3d   %3d  %.0e%c %s %-6s %12s %s\n",
           C2z.clone, C2z.left, C2z.right, C2z.nbands, Sz.olap, Sz.match, 
           Sz.olap-Sz.match, Sz.prob, ch, mk,  Sz.msg1, C2z.parent, 
           C2z.btype); 
          Output;
     }
  }
  sprintf(scoreText,"Eval %s  Bad Olap %d of %d",C1z.clone, cnt_bad, cnt); Show;
  if (Zlogfp) fflush(Zlogfp);
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: C1zMark
compare clone 1 against contig for shared markers
****************************************************************/
static void C1zMark()
{
int  index1, cnt=0;
struct contig *p;
char c;
int score, x, y, x1, y1, ctg;

  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!Zall_ok(1,1)) return;
  if (!loadCz(&C1z, index1)) {
      sprintf(scoreText,"Cannot eval clone %s",set1Text); Show;
      strcpy(ZBuf, scoreText); Output;
      return;
  }
  ctg = arr(acedata, C1z.cin, CLONE).ctg;
  if (ctg==currentctg)
      ZhighCin(CLAM_CLONE, C1z.cin);
  x = arr(acedata, C1z.cin, CLONE).x;
  y = arr(acedata, C1z.cin, CLONE).y;
  sprintf(ZBuf,"\n>> --> Ctg%d Markers %s %db %3d %3d (Tol %d Cutoff %.0e%s %s)\n",
            ctg, set1Text, C1z.nbands, x, y, Pz.tol, Pz.cutFlt,
            CpMtype[Cp.useFlag], hidestate[showburied]); Output;
  
  for (p=root; p!=NULL; p = p->new)
  {
     if (!loadCz(&C2z, p->next)) continue;
     if (strcmp(C1z.clone, C2z.clone)==0) continue;
     if (showburied==1 && C2z.parent[0]!=' ') continue; 
     if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
     score = Zcnt_shared_markers(&C1z,&C2z,&Sz);
     if (score > 0) {
        Zsulston(&C1z,&C2z,&Sz);
        if (ZboolCpM()) ZhighP(CLAM, p);
        else ZhighP(CLAM_WEAK, p);
        cnt++;

        c=' ';
        x1 = arr(acedata, C2z.cin, CLONE).x;
        y1 = arr(acedata, C2z.cin, CLONE).y;
        if (ctg==currentctg) 
          if (y1 < x || x1 > y) c='*';  

        sprintf(ZBuf, "%12s (%3d,%3d)%c %2db %2d %.0e  %d\n",
           C2z.clone, x1, y1, c, C2z.nbands, Sz.match, Sz.prob, score); 
        Output;
     }
  }
  sprintf(scoreText,"%s matches %d clones in Ctg",set1Text, cnt); Show;
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: C1zCtg
compare clone 1 against contig for sulston score
****************************************************************/
static void C1zCtg()
{
int  stat, index1, cnt=0;
struct contig *p;
char c, s[30], mk[20];
int x, y, x1, y1, ctg;
double  best_score=10.0;
int best_i=-1;

  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!Zall_ok(1,1)) return;
  if (!loadCz(&C1z, index1)) {
      sprintf(scoreText,"Cannot eval clone %s",set1Text); Show;
      strcpy(ZBuf, scoreText); Output;
      return;
  }
  ctg = arr(acedata, C1z.cin, CLONE).ctg;
  if (ctg==currentctg)
      ZhighCin(CLAM_CLONE, C1z.cin);
  x = arr(acedata, C1z.cin, CLONE).x;
  y = arr(acedata, C1z.cin, CLONE).y;
  sprintf(ZBuf,"\n>> --> Ctg%d %s %db (%3d, %3d) (Tol %d Cutoff %.0e%s %s)\n",
                ctg, set1Text, C1z.nbands, x, y, Pz.tol, Pz.cutFlt,
                CpMtype[Cp.useFlag], hidestate[showburied]); Output;
  
  for (p=root; p!=NULL; p = p->new)
  {
     if (!loadCz(&C2z, p->next)) continue;
     if (strcmp(C1z.clone, C2z.clone)==0) continue;
     if (showburied==1 && C2z.parent[0]!=' ') continue; 
     if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
     Zsulston(&C1z,&C2z,&Sz);
     if (ZboolCpM()) { 
        cnt++;
        if (Sz.mark > 0) ZhighP(CLAM, p);
        else ZhighP(CLAM_WEAK, p);
        if (Sz.prob <= best_score) {
            best_score = Sz.prob;
            best_i = p->next;
        }
        stat = arr(acedata, p->next, CLONE).seqstat;
        if (stat!= 0) strcpy(s, seqstat[stat]);
        else strcpy(s, "        ");
        c=' ';
        x1 = arr(acedata, C2z.cin, CLONE).x;
        y1 = arr(acedata, C2z.cin, CLONE).y;
        if (ctg==currentctg) 
          if (y1 < x || x1 > y) c='*';  
        if (Sz.mark > 0) sprintf(mk,"%2d",Sz.mark);
        else strcpy(mk, "  ");
        sprintf(ZBuf, "%12s (%3d,%3d)%c %2db %2d %.0e %s %12s %s\n",
        C2z.clone, x1, y1, c, C2z.nbands, Sz.match, Sz.prob, mk, C2z.parent, s);
        Output;
     }
  }
  if (best_i == -1)
     sprintf(scoreText,"No match.");
  else sprintf(scoreText,"Best match %s %.0e",
        arrp(acedata, best_i, CLONE)->clone, best_score); 
  Show;
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: C1zBur
This is rarely if ever used, and henced, moved to Rule Menu.
****************************************************************/
void C1zBur()
{
int  cnt1=0, cnt2=0, cnt3=0, cnt4=0, index1;
struct contig *p;

  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!loadCz(&C1z, index1)) {
      sprintf(scoreText,"Cannot eval clone %s",set1Text); Show;
      strcpy(ZBuf, scoreText); Output;
      return;
  }

  ZhighCin(CLAM_CLONE, C1z.cin);
  
  sprintf(ZBuf,"\n>> Buried %s %db %12s %s (Tol %d, Bury~ %3.3f)\n",
                set1Text, C1z.nbands, C1z.parent, C1z.btype, 
                Pz.tol, Pz.burFlt); Output;
  for (p=root; p!=NULL; p = p->new)
  {
     if (!loadCz(&C2z, p->next)) continue;
     if (strcmp(C1z.clone, C2z.clone)==0) continue;
     Zgetmatch(&C1z,&C2z,&Sz);
     if (strcmp(C2z.parent, C1z.clone)==0) { /* 2 in 1 */
         if (IsBuried(C2z.nbands)) {
             sprintf(ZBuf, "Good Child  %12s %2db  match %d %s\n",
                 C2z.clone, C2z.nbands, Sz.match, C2z.btype); Output;
             cnt1++;
         }
         else {
             sprintf(ZBuf, "Bad  Child  %12s %2db  match %d %s\n",
                 C2z.clone, C2z.nbands, Sz.match, C2z.btype); Output;
             ZhighP(LIGHTRED, p); 
             cnt2++;
         }
     }
     else if (strcmp(C1z.parent, C2z.clone)==0) { /* 1 in 2 */
         if (IsBuried(C1z.nbands)) {
             sprintf(ZBuf, "Good Parent %12s %2db  match %d\n",
                 C2z.clone, C2z.nbands, Sz.match); Output;
             cnt1++;
         }
         else {
             sprintf(ZBuf, "Bad  Parent %12s %2db  match %d\n",
                 C2z.clone, C2z.nbands, Sz.match); Output;
             ZhighP(LIGHTRED, p); 
             cnt2++;
         }
     }
     else if (IsBuried(C2z.nbands)) {
        if (C2z.parent[0]!=' ')
             sprintf(ZBuf, "New  Child  %12s %2db  match %2d  Existing parent %s %s\n",
                 C2z.clone, C2z.nbands, Sz.match, C2z.parent, C2z.btype); 
        else
             sprintf(ZBuf, "New  Child  %12s %2db  match %d \n",
                 C2z.clone, C2z.nbands, Sz.match); 
        Output;
        ZhighP(CLAM, p); 
        cnt3++;
     }
     else if (IsBuried(C1z.nbands)) {
        if (C2z.parent[0]!=' ')
           sprintf(ZBuf, "New  Parent %12s  %2db  match %d who has parent %s %s\n",
                 C2z.clone, C2z.nbands, Sz.match, C2z.parent, C2z.btype); 
        else
           sprintf(ZBuf, "New  Parent %12s  %2db  match %d\n",
                 C2z.clone, C2z.nbands, Sz.match); 
        Output;
        ZhighP(CLAM_PARENT, p); 
        cnt4++;
     }
  }
sprintf(scoreText,"Good %d Bad %d Child %d Parent %d",cnt1,cnt2,cnt3,cnt4); Show;
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: C1zDb
clone against all db not in contig
****************************************************************/
static void C1zDb()
{
int i, cnt;
int  index1, stat;
char mk[10], s[20];

  if (!Zall_ok(1,1)) return;
  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!loadCz(&C1z, index1)) return;
  ZhighCin(CLAM_CLONE, C1z.cin);

  sprintf(ZBuf, "\n>> --> Fpc %s %db %s (Tol %d Cutoff %.0e%s)\n", 
     C1z.clone, C1z.nbands, C1z.btype, Pz.tol, Pz.cutFlt,
     CpMtype[Cp.useFlag]); Output;

  for (cnt=i=0; i< arrayMax(acedata); i++) 
  {
     if (!loadCz(&C2z, i)) continue;
     if (strcmp(C2z.clone, C1z.clone)==0) continue;
     if (currentctg == C2z.ctg) continue;
     if (C2z.clone[0]== '!') continue; 
     Zsulston(&C1z,&C2z,&Sz);
     if (ZboolCpM()) {
        stat = arr(acedata, i, CLONE).seqstat;
        if (stat!= 0) strcpy(s, seqstat[stat]);
        else s[0] = '\0';

        if (Sz.mark > 0) sprintf(mk, "%2d",Sz.mark);
        else strcpy(mk,"  ");
        sprintf(ZBuf, "Ctg%-4d %12s %2db   %3d %.0e %s %12s %s %s\n",
           C2z.ctg, C2z.clone, C2z.nbands, Sz.match, Sz.prob, mk,
           C2z.parent,C2z.btype,s); Output;
        cnt++;
     }
     if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of -->\n");
          break;
     } 
  }
  sprintf(scoreText,"%s matches %d clones in Fpc",set1Text, cnt); Show;
  if (Zlogfp) fflush(Zlogfp);
  if(ctg_window!=NULL) refresh_all_track_colors();
}  
/*********************************************************88
                     DEF: SetMatch
************************************************************/
extern float f_unc;

static void SetMatch()
{
int i;
int  rc1, rc2, var, total=0, tot, index1, index2;
char tmp[10];

  if (!Zall_ok(1, 1)) return;
  removespaces(set1Text);
  if(!fppFindClone(set1Text,&index1)) {   /* find clone */
      sprintf(scoreText,"ERROR could not find clone1 %s",set1Text); Show;
      return;
  }
  if (!loadCz(&C1z, index1)) return;
  rc1 = loadSizeCz(&C1z, index1);
  if (Pz.stdFlag || Pz.logFlag) {
     sprintf(ZBuf, "\n>> Compare %s %s  (Tol %d)\n", 
                   set1Text, set2Text, Pz.tol); Output;
     ZBuf[0] = '\0';
  } 
  ZhighCin(CLAM_CLONE, C1z.cin);
  removespaces(set2Text);
  if(!fppFindClone(set2Text,&index2)) {   /* find clone */
      sprintf(scoreText,"ERROR could not find clone2 %s",set2Text); Show;
      return;
  }
  if (!loadCz(&C2z, index2)) return;
  rc2 = loadSizeCz(&C2z, index2);
  var = Proj.variable;

  if (rc1 && rc2) {
     Proj.variable=1;
     clear_Zunc();
  }

  ZhighCin(CLAM_CLONE, C2z.cin);

  calc_olap();
  Zsulston(&C1z,&C2z,&Sz);

  if (Pz.stdFlag || Pz.logFlag) {
     int k, lstart, idiff, kbnd, l;

     for (tot=i=0; i< C1z.nbands; i++) tot += C1z.coords[i];
     sprintf(ZBuf, "%12s %4d,%4d %2db %12s %s     total  %d\n",
              C1z.clone,  C1z.left, C1z.right, 
                   C1z.nbands, C1z.parent, C1z.btype, tot); Output;
     for (tot=i=0; i< C2z.nbands; i++) tot += C2z.coords[i];
     sprintf(ZBuf, "%12s %4d,%4d %2db %12s %s     total  %d\n",
        C2z.clone,  C2z.left, C2z.right, C2z.nbands,
                C2z.parent, C2z.btype, tot); Output;
     tmp[0] = ZBuf[0] = '\0';

     if (Proj.variable)
        sprintf(ZBuf, "Clone1 Clone2       Diff   Tol\n");
     else
        sprintf(ZBuf, "Clone1 Clone2     Diff  \n");
     Output;
     lstart = 0;
     for (i = k = 0; k < C1z.nbands; ++k)
     {
         kbnd = C1z.coords[k];
         for (l = lstart; l < C2z.nbands; ++l)
         {
             idiff = kbnd - C2z.coords[l];
             if (Ztol(kbnd, idiff))
             {
                if (Proj.variable) sprintf(tmp,"%4.1f",  f_unc);
                sprintf(ZBuf, "%6d %6d %5d       %s\n", 
                         kbnd, C2z.coords[l], idiff,tmp);
                total+= (kbnd+C2z.coords[l])/2;
                Output;
                lstart = l + 1;
                if (lstart==C2z.nbands) k++;
                goto L100;
             }
             else if (idiff < 0)
             {
                if (Proj.variable) sprintf(tmp,"%4.1f",  f_unc);
                sprintf(ZBuf, "%6d             %5d  %s\n", kbnd,  idiff,tmp);
                Output;
                lstart = l;
                goto L100;
             }
             else {
                if (Proj.variable) sprintf(tmp,"%4.1f",  f_unc);
                sprintf(ZBuf, "       %6d      %5d  %s\n",  
                     C2z.coords[l],idiff, tmp);
                Output;
                if (l==C2z.nbands-1) lstart = C2z.nbands;
             }
         }
L100: ;
      if (lstart==C2z.nbands) break;
      }
      for (; k < C1z.nbands; ++k) {
                sprintf(ZBuf, "%6d            \n", C1z.coords[k]);
                Output;
             }
      for (l=lstart; l < C2z.nbands; ++l) {
                sprintf(ZBuf, "       %6d    \n",  C2z.coords[l]);
                Output;
             }
  }
  if (Proj.variable) {
    sprintf(scoreText,"Olap %d Match %d %.0e (Nsizes %d %d)",
           Sz.olap, Sz.match, Sz.prob, C1z.nbands, C2z.nbands); Show;
    sprintf(ZBuf,"%s\n",scoreText); Output;
    sprintf(ZBuf,"Total size overlap %d  Shared markers %d\n", 
             total,  Zcnt_shared_markers(&C1z,&C2z,&Sz)); Output;
  }
  else  {
    sprintf(scoreText,"Olap %d Match %d %.0e (Nbands %d %d)",
           Sz.olap, Sz.match, Sz.prob, C1z.nbands, C2z.nbands); Show;
    sprintf(ZBuf,"%s\n",scoreText); Output;
    sprintf(ZBuf,"Total band overlap %d  Shared markers %d\n", 
             total,  Zcnt_shared_markers(&C1z,&C2z,&Sz)); Output;
  }
  if (Zlogfp) fflush(Zlogfp);
  Proj.variable = var;
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/***********************************************************
                     DEF: calc_olap
************************************************************/
static void calc_olap()
{
   Sz.msg1[0] = '\0';
   Sz.olap = Sz.burdiff = Sz.olapdiff = 0;
   
   if (C1z.left == C2z.left && C1z.right ==  C2z.right) {
        strcpy(Sz.msg1,"Equal");
        Sz.olap = (C2z.right - C2z.left)+1;
   }
   else if (C1z.left <= C2z.left && C2z.right <=   C1z.right) {
        strcpy(Sz.msg1,"Inside");
        Sz.olap = C2z.len;
   }
   else if (C2z.left <= C1z.left &&  C1z.right <=  C2z.right) {
        strcpy(Sz.msg1,"Spans");
        Sz.olap = C1z.len;
   }
   else if (C1z.left >= C2z.left && C1z.left <=  C2z.right) {
        Sz.olap = (C2z.right - C1z.left) + 1;
   }
   else if ( C1z.right >= C2z.left &&  C1z.right <=  C2z.right) {
        Sz.olap =  (C1z.right - C2z.left) +1;
   }
}
/***********************************************************
                     DEF: do_Ends
************************************************************/
static void do_Ends(char *msg, int type)
{
int i, c, cnt, found, high_ctg, high_cnt;
int  left, right, score;
char  ch1='\0', ch2='\0';
CLONE *clp, *clp2;
struct contig *p;

  ZBufPrint = (char *)(malloc (sizeof(char) * ZBufSize ));
  ZBufPtr = ZBufPrint;

  if (!Zall_ok(1, 1)) return;

  sprintf(ZBuf, 
  "\n>> %s --> Ends Ctg%d  (Tol %d  Cutoff %.0e%s  FromEnds %d)\n", 
      msg, currentctg,  Pz.tol, Pz.cutFlt, CpMtype[Cp.useFlag], Pz.fromendInt); Output;
  high_ctg = high_cnt = 0;

  for (found=0, i=1; i<=max_contig; i++) 
  {
       if (i==currentctg) continue; 
       if (contigs[i].count == 0) continue;
       if (contigs[i].ctgstat== DEAD) continue; /* CHG 25may01 */

       cnt=0;
       for (p=root; p!=NULL; p = p->new)
       {
           if (graphInterruptCalled()) {
               printf("User Interrupt - pre-mature termination of --> Ends\n");
               return;
           } 
           clp = arrp(acedata, p->next, CLONE);
           if (type==1 && !EndClone(clp, currentctg)) continue;
           else if (type==0) if (!clp->selected) continue;
           if (!loadCz(&C1z, p->next)) continue;
           left = abs(clp->x - contigs[currentctg].left);
           right = abs(clp->y - contigs[currentctg].right);
           if (left<= Pz.fromendInt && left < right) ch1 = 'L'; /* 3jan00 FIX */
           else if (right <= Pz.fromendInt) ch1 = 'R';

           for (c= contigs[i].start; c != -1; c= clp2->next)
           {
              clp2 = arrp(acedata, c, CLONE);
              if (!EndClone(clp2, i)) continue;
              if (!loadCz(&C2z, c)) continue;

              Zsulston(&C1z,&C2z,&Sz);
              score = ZscoreCpM(&C1z,&C2z,&Sz);
              if (score == 0) continue;
              cnt++; 
              if (Pz.stdFlag || Pz.logFlag) {
                  left = abs(clp2->x - contigs[i].left);
                  right = abs(clp2->y - contigs[i].right);
                  if (left<= Pz.fromendInt && left < right) ch2 = 'L'; /* 3jan00 FIX */
                  else  ch2 = 'R';
                  ZhighP(CLAM, p);
                  Out_ends(ch1, ch2);
			      if (ZBufPtr != ZBufPrint)
			      {
				      ZBufPtr=ZBufPrint;
				      if (Pz.logFlag) 
				      {
					      fprintf(Zlogfp,"%s",ZBufPrint); 
					      fflush(Zlogfp);
				      } 

      				  else if (!Zbatch_flag && Pz.stdFlag)
				      {
					      printf("%s",ZBufPrint); 
					      fflush(stdout);
				      }
				      memset(ZBufPrint,0,strlen(ZBufPrint));
			      }
              }
           }
       }
       if (cnt>high_cnt) {
          high_cnt=cnt;
          high_ctg= i;
       }
  }
  sprintf(scoreText,"%s --> Ends Best Ctg%d %d", msg, high_ctg, high_cnt); Show;
  sprintf(ZBuf,"%s\n",scoreText); Output;
  if (Zlogfp) fflush(Zlogfp);
  if(ctg_window!=NULL) refresh_all_track_colors();

  //free the allocated memory for ZBufPrint
  if(ZBufPrint)
  {
	free(ZBufPrint);
	ZBufPrint = NULL;
	ZBufPtr = NULL;
  }
}
/*********************************************************88
                     DEF: SelEnds
************************************************************/
static void SelEnds()
{
    do_Ends("Selected", 0);
}
/*********************************************************88
                     DEF: CtgEnds
************************************************************/
static void CtgEnds()
{
    do_Ends("Ends", 1);
}
/*********************************************************88
                     DEF: DoCtgCheck
************************************************************/
static int DoCtgCheck(struct contig *p, int stepflag)
{
struct contig  *q;
int last_right, next_right, best_i, best_left, best_right;
int last_left, next_left;
double best_score;
int flag;
int high[100], h=0;

     best_i = -1;
     best_score = 10.0;
     flag = -1;     
     last_left = next_left = next_right = best_left = best_right = -1;     
     for (q=root; q!=NULL; q = q->new)
     {
         if (!loadCz(&C2z, q->next)) continue;
         if (showburied==1 && C2z.parent[0]!=' ') continue; 
         if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
         if (strcmp(C1z.clone, C2z.clone)==0) {
             flag = 1;
             continue;
         }
         if (flag== -1) {
             last_left = C2z.left;
             last_right = C2z.right;
         }
         else if (flag==1) {
             next_left = C2z.left;
             next_right = C2z.right;
             flag = 2;
         }
         calc_olap();
         Zsulston(&C1z,&C2z,&Sz);
         if (Sz.prob > Pz.cutFlt) continue;
         if (stepflag && h<100) high[h++] = q->next;
         if (Sz.prob < best_score) {
             best_score = Sz.prob;
             best_i = C2z.cin;
             best_left = C2z.left;
             best_right = C2z.right;
         }
     }
     if (best_i == -1) return 0;
     if (best_left <= next_left && best_right >= next_right) flag = 1;
     else if (best_left <= last_left && best_right >= last_left) flag = 1;
     else if (best_left <= C1z.left && best_right >= C1z.right) flag = 1;
     else if (best_left >= C1z.left && best_right <= C1z.right) flag = 1;
     else flag = 0;
     if (!flag) {
          ZhighCin(RED, C1z.cin);
          if (stepflag) {
              if (p->box==0) {
                 centre_pos = arrp(acedata,p->next, CLONE)->x;
                 if(ctg_window!=NULL) refresh_all_track_colors();
              }
              ZhighCin(LIGHTRED, best_i);
              if(ctg_window!=NULL) refresh_all_track_colors();
          }
          sprintf(ZBuf,"%12s %12s   %.0e \n", C1z.clone, 
               arrp(acedata, best_i, CLONE)->clone, best_score); Output;
          return 1;
     }
     else return 0;
}
/*********************************************************88
                     DEF: CtgStep
************************************************************/
static void CtgStep()
{
CLONE clone;
struct contig *p;
static int ctg=0, cnt=0;

  if (!Zall_ok(1, 1)) return;
  if (currentctg!=ctg) Ctgstep = root;
  else if (Ctgstep==NULL) Ctgstep = root;
  ctg = currentctg;
  if (Ctgstep==root) cnt=0;

  for (p=Ctgstep; p!=NULL; p = p->new)
  {
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of CtgCheck\n");
          return;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
     if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
     if (!loadCz(&C1z, p->next)) continue;

     if (DoCtgCheck(p, 1)) {
         cnt++;
         sprintf(scoreText,"CtgCheck #%d",cnt); Show; 
         Ctgstep = p->new;
         return;
     }
  }
  Ctgstep=NULL;
  printf("Stepped through %d CtgCheck\n", cnt);
  sprintf(scoreText,"Stepped through %d CtgCheck",cnt); Show; 
}
/****************************************************************
                      DEF: CtgCheck
****************************************************************/
static void CtgCheck()
{
CLONE clone;
int cnt=0;
struct contig *p;

  if (!Zall_ok(1, 1)) return;
  Ctgstep=NULL;
  clhigh=NULL;    /* cari 6aug04 - highlighted clones do not get highlighted if bad */

  sprintf(ZBuf, 
  "\n>> Check Ctg%d  (Tol %d, Cutoff %.0e)\n", 
                   currentctg,  Pz.tol, Pz.cutFlt); Output;
  for (p=root; p!=NULL; p = p->new)
  {
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of CtgCheck\n");
          goto DONE;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (showburied==1 && clone.match[0]!=' ') continue; 
     if (showburied==2 && clone.mattype == PSEUDO) continue; 
     if (!loadCz(&C1z, p->next)) continue;

     cnt += DoCtgCheck(p,0);
  }
DONE: ;
  sprintf(scoreText,"Contig has %d pair of bad clones",cnt); Show; 
  sprintf(ZBuf,"Contig has %d bad clones\n",cnt); Output;
  if (Zlogfp) fflush(Zlogfp);
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: BadCtg
****************************************************************/
static void BadCtg()
{
CLONE clone;
struct contig *p, *q;
int cnt=0;

  if (!Zall_ok(1, 1)) return;
  clhigh=NULL;    /* cari 6aug04 - highlighted clones do not get highlighted if bad */
  sprintf(ZBuf, 
  "\n>> BadOlap Ctg%d  (Tol %d  Cutoff %.0e  if Abs(Olap-M) > %d)\n", 
                   currentctg,  Pz.tol, Pz.cutFlt, Pz.diffInt); Output;

  for (p=root; p!=NULL; p = p->new)
  {
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of Eval Ctg\n");
          return;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
     if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
     if (!loadCz(&C1z, p->next)) continue;

     for (q=p->new; q!=NULL; q = q->new)
     {
         if (!loadCz(&C2z, q->next)) continue;
         if (showburied==1 && C2z.parent[0]!=' ') continue; 
         if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
         if (strcmp(C1z.clone, C2z.clone)==0) continue;
         calc_olap();
         Zsulston(&C1z,&C2z,&Sz);

         if(Sz.olap==0) continue;
         if (BadOlap(Sz.olap, Sz.match)) {
                sprintf(ZBuf,"%12s %12s   Olap=%2d M=%2d  %3d\n", C1z.clone, C2z.clone, Sz.olap,
                       Sz.match, Sz.olap-Sz.match); Output;
               ZhighCin(LIGHTRED, C1z.cin);
               ZhighCin(LIGHTRED, C2z.cin);
               cnt++;
         }
     }
  }
  sprintf(scoreText,"Contig has %d pair of bad clones",cnt); Show; 
  sprintf(ZBuf,"Contig has %d bad clones\n",cnt); Output;
  if (Zlogfp) fflush(Zlogfp);
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/****************************************************************
                      DEF: NoStep
****************************************************************/
static void NoStep()
{
CLONE clone;
struct contig *p, *q;
int d;
static int ctg=0, cnt=0, cntp;

  if (!Zall_ok(1, 1)) return;
  if (currentctg!=ctg) Nostep = root;
  else if (Nostep==NULL) Nostep = root;
  if (Nostep==root) cnt=0;
  ctg = currentctg;

  for (p=Nostep; p!=NULL; p = p->new)
  {
     cntp=0;
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of Eval Ctg\n");
          return;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
     if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
     if (!loadCz(&C1z, p->next)) continue;

     for (q=root; q!=NULL; q = q->new)
     {
         if (!loadCz(&C2z, q->next)) continue;
         if (showburied==1 && C2z.parent[0]!=' ') continue; 
         if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
         if (strcmp(C1z.clone, C2z.clone)==0) continue;
         calc_olap();
         Zsulston(&C1z,&C2z,&Sz);

         if (Sz.olap==0 && ZboolCpM()) {
               if (C1z.right < C2z.left) d = (C2z.left-C1z.right)+1;
               else d = (C1z.left-C2z.right)+1;
               sprintf(ZBuf,"%12s %12s   Distance %-3d  %.0e \n", 
                   C1z.clone, C2z.clone, d, Sz.prob); Output;
               ZhighCin(LIGHTRED, C2z.cin);
               if (p->box==0) {
                   centre_pos = arrp(acedata,p->next, CLONE)->x;
                   /* ctgdisplay(currentctg); fred 5/7/03*/
                   if(ctg_window!=NULL) refresh_all_track_colors();
               }
               cntp++;
         } 
     }
     Nostep = p->new;
     if (cntp>0) {
        cnt++;
        ZhighCin(RED, C1z.cin);
        if(ctg_window!=NULL) refresh_all_track_colors();
        sprintf(scoreText,"NoOlap #%d %s %d",cnt, C1z.clone, cntp); Show; 
        return;
     }
  }
  Nostep=NULL;
  printf("Step NoOlap done with %d bad clones\n", cnt);
  sprintf(scoreText,"Step NoOlap done"); Show; 
}
/****************************************************************
                      DEF: EvalCtg
****************************************************************/
static void EvalCtg()
{
CLONE clone;
struct contig *p, *q;
int cnt=0;
int d;
char mk[10];

  if (!Zall_ok(1, 1)) return;

  clhigh=NULL;    /* cari 6aug04 - highlighted clones do not get highlighted if bad */
  sprintf(ZBuf, 
  "\n>> NoOlap Ctg%d  (Tol %d Cutoff %.0e%s)\n", 
       currentctg,  Pz.tol, Pz.cutFlt, CpMtype[Cp.useFlag]); Output;
  for (p=root; p!=NULL; p = p->new)
  {
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of Eval Ctg\n");
          goto DONE;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
     if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
     if (!loadCz(&C1z, p->next)) continue;

     for (q=p->new; q!=NULL; q = q->new)
     {
         if (!loadCz(&C2z, q->next)) continue;
         if (showburied==1 && C2z.parent[0]!=' ') continue; 
         if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
         if (strcmp(C1z.clone, C2z.clone)==0) continue;
         calc_olap();
         Zsulston(&C1z,&C2z,&Sz);

         if (Sz.olap==0 && ZboolCpM()) {
               if (Sz.mark > 0) sprintf(mk,"%d",Sz.mark);
               else mk[0]='\0';
               if (C1z.right < C2z.left) d = (C2z.left-C1z.right)+1;
               else d = (C1z.left-C2z.right)+1;
               sprintf(ZBuf,"%12s %12s   Distance %-3d  %.0e %s\n", 
                   C1z.clone, C2z.clone, d, Sz.prob, mk); Output;
               ZhighCin(LIGHTRED, C1z.cin);
               ZhighCin(LIGHTRED, C2z.cin);
               cnt++;
         } 
     }
  }
DONE: ;
  sprintf(scoreText,"Contig has %d pair of bad clones",cnt); Show; 
  sprintf(ZBuf,"Contig has %d bad clones\n",cnt); Output;
  if (Zlogfp) fflush(Zlogfp);
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/*****************************************************************
                   DEF: Eval Mark
******************************************************************/
static void EvalMark()
{
struct markerctgpos *cp;
struct markerclone *clones;
struct marker *marker;
struct markerlist *p;
int total=0, cnt1, cnt2,cnt3, x;
CLONE *clp;
int  num,  done;
int i,j;
struct {
   int left, right, cin;
} tmp, cl[CLONE_MARKER_MAX];

  Zall_ok(0, 1);
  if(ctg_window==NULL)
    return;

  for(p=markerlistroot; p != NULL; p = p->next)
  {
     cnt1=cnt2=cnt3= 0;
     marker = arrp(markerdata,p->markerindex,MARKER);

     if (markctgFlag) {
        for (cp=marker->pos; cp!=NULL; cp=cp->next) 
              if(cp->ctg != 0) cnt1++;
        if (cnt1> 1) { 
          sprintf(ZBuf,"Marker %s in %d contigs\n",marker->marker, cnt1);
          Output;
        }
     }

     if (markclFlag) {
        if (arr(acedata, marker->cloneindex, CLONE).ctg == currentctg)
                           cnt2++;
        for (clones = marker->nextclone; clones != NULL; 
             clones = clones->nextclone) 
                if (arr(acedata, clones->cloneindex, CLONE).ctg == currentctg)
                           cnt2++;
        if (cnt2==1) {
          sprintf(ZBuf,"Marker %s OneClone %s\n",marker->marker, 
                   arr(acedata, marker->cloneindex, CLONE).clone);
          Output;
        }
     } 

     if (marksplitFlag) {
        num=0;
        clp = arrp(acedata, marker->cloneindex, CLONE);
        if (clp->ctg == currentctg) {
          if (clp->parent!=-1) clp = arrp(acedata,clp->parent, CLONE);
          cl[num].cin = marker->cloneindex;
          cl[num].left = clp->x;
          cl[num].right = clp->y;
          num++;
          if (num==CLONE_MARKER_MAX) {
             printf("Exceeded limit (%d) for markers in a clone %s\n",
                     CLONE_MARKER_MAX,clp->clone);
             return;
          }
        } 
        for (clones = marker->nextclone; clones != NULL; clones = clones->nextclone) {
             clp = arrp(acedata, clones->cloneindex, CLONE);
             if (clp->ctg == currentctg) {
               if (clp->parent!=-1) clp = arrp(acedata,clp->parent, CLONE);
               cl[num].cin= clones->cloneindex;
               cl[num].left = clp->x;
               cl[num].right = clp->y;
               num++;
             } 
        }
        for (i=0; i<num-1; i++) 
          for (j=i+1; j<num; j++)
             if (cl[i].right>cl[j].right) {
                tmp = cl[i];
                cl[i] = cl[j];
                cl[j] = tmp;
             }
        for (i=0; i<num-1; i++) 
        {
           for (x=-1, done=0, j=i+1; j<num && !done; j++)
           {
              if (cl[i].right>=cl[j].left) done=1;
              else if (x==-1) x = j;
              else if (cl[x].left > cl[j].left) x=j;
           }
           if (done==0 && x!=-1) {
              loadCzfast(&C1z, cl[i].cin);
              loadCzfast(&C2z, cl[x].cin);
              Zsulston(&C1z,&C2z,&Sz);
              sprintf(ZBuf,"Marker %-16s split at %-12s %-12s cutoff %.0e\n",
                marker->marker, arr(acedata, cl[i].cin, CLONE).clone,
                arr(acedata, cl[x].cin, CLONE).clone, Sz.prob);
              Output;
              cnt3++;
           }
        } 
     }
     if (cnt1 > 1 || cnt2 == 1 || cnt3 > 0) {
         total++;
         marker->colour = LIGHTRED;
         if (marker->box != 0)
           graphBoxDraw(marker->box, BLACK, marker->colour);
     }
  }
  sprintf(scoreText, "Eval markers %d ", total); Show;
  if(ctg_window!=NULL) refresh_all_track_colors();
}
/*****************************************************************
                   Def: SplitMarker
*****************************************************************/
static void SplitMarker()
{
  printf(">>Split markers ctg%d\n", currentctg); 
  markctgFlag=0;
  marksplitFlag=1;
  markclFlag=0;
  EvalMark();
}
/*****************************************************************
                   Def: OneClone
*****************************************************************/
static void OneClone()
{
  printf(">> Markers hitting one clone ctg%d\n", currentctg); 
  markctgFlag=0;
  marksplitFlag=0;
  markclFlag=1;
  EvalMark();
}
/*****************************************************************
                   Def: MultCtg
*****************************************************************/
static void MultCtg()
{
  printf(">> Markers hitting multiple contigs ctg%d\n", currentctg); 
  markctgFlag=1;
  marksplitFlag=0;
  markclFlag=0;
  EvalMark();
}
/*****************************************************************
                   Def: FindOrphans
*****************************************************************/
static void FindOrphans()
{
int found, cnt;
struct contig *p, *q;
CLONE clone;

  if (!Zall_ok(1, 3)) return;

  sprintf(ZBuf, 
  "\n>> Orphans Ctg%d  (Tol %d Cutoff %.0e%s)\n", 
       currentctg,  Pz.tol, Pz.cutFlt, CpMtype[Cp.useFlag]); Output;

  for (cnt=0, p=root; p!=NULL; p = p->new)
  {
      if (graphInterruptCalled()) {
          printf("User Interrupt - pre-mature termination of Eval Ctg\n");
          return;
      } 
     clone = arr(acedata, p->next, CLONE);
     if (clone.fp == NULL)  continue;
     if (!loadCz(&C1z, p->next)) continue;

     for (found=0, q=root; q!=NULL && found==0; q = q->new)
     {
         if (!loadCz(&C2z, q->next)) continue;
         if (strcmp(C1z.clone, C2z.clone)==0) continue;
         calc_olap();
         Zsulston(&C1z,&C2z,&Sz);

         if (ZboolCpM()) found=1;
     }
     if (!found) {
        cnt++;
        ZhighCin(RED, C1z.cin);
        sprintf(ZBuf,"Orphan %s\n", C1z.clone); Output; 
     }
  }
  sprintf(scoreText, "Orphans %d ", cnt); Show;
  if(ctg_window!=NULL) refresh_all_track_colors();
}

/* */
/* sness!!!! */
/* */

/* */
/* snDoCtgCheck - More useful CtgCheck functionality */
/* */
/* The old CtgCheck and CtgStep functions were more useful for */
/* debugging the contig building algorithm, these new contig checkers */
/* are now on the "Contig Display" page as buttons snCtgCheck and */
/* snCtgStep.  They iterate through all clones in a contig and */
/* check to make sure that for each clone, it is flanked on either */
/* side by it's best and second best neighbours.  If not, it's */
/* flagged. */

/* For snCtgCheck, all such clones are highlighted in CYAN */

/* For snCtgStep, we iterate through the contig, if we find a clone */
/* whose best and second best neighbours are not flanking it, we */
/* highlight the current clone in CYAN, the best neighbour in */
/* LIGHTGREEN and the second best neighbour in LIGHTBLUE. */
/* *******************************/
/* ************fred 4/16/03 -- changed CYAN to RED, as its more appropriate*/
/* *******************************/

static int snDoCtgCheck(struct contig *p, int stepflag)
{
  struct contig  *q;
  int flag;
  int before=-1;  /* Clone before current clone */
  int after=-1;   /* Clone after current clone */
  int best_i;  /* Best neighbour to current clone */
  int next_best_i; /* Next best neighbour */
  double before_score; /* Score of "before" clone */
  double after_score;  /* Score of "after" clone */
  double best_score;   /* Score of best clone */
  double next_best_score;   /* Score of best clone */

  best_i = next_best_i = -1;
  best_score = next_best_score = 10.0;
  flag = -1;

  for (q=root; q!=NULL; q = q->new) {
	if (!loadCz(&C2z, q->next)) continue;
	if (showburied==1 && C2z.parent[0]!=' ') continue; 
	if (showburied==2 && strcmp(C2z.btype, "pseudo")==0) continue; 
	if (strcmp(C1z.clone, C2z.clone)==0) {
	  flag = 1;
	  continue;
	}
	/* Calculate score */
	calc_olap();
	Zsulston(&C1z,&C2z,&Sz);

/*    	printf("DEBUG:Clone1=%12s Clone2=%12s  Score=%.0e\n", C1z.clone, C2z.clone, Sz.prob);  */

	if (flag== -1) {  /* Before our clone (C1z) */
	  before = C2z.cin;
	  before_score = Sz.prob;
	}
	else if (flag==1) { /* At our clone (C1z) */
	  after = C2z.cin;
	  after_score = Sz.prob;
	  flag = 2;
	}

	if (Sz.prob < best_score) {
  	  if (next_best_i == -1) {
  		next_best_score = Sz.prob;
  		next_best_i = C2z.cin;
  	  } else {
		next_best_score = best_score;
		next_best_i = best_i;
  	  }
	  best_score = Sz.prob;
	  best_i = C2z.cin;
	} else if (Sz.prob < next_best_score) {
	  next_best_score = Sz.prob;
	  next_best_i = C2z.cin;
	}

  }
  if (best_i == -1) return 0;

  if (((before == best_i) || (after == best_i)) && 
	  ((before == next_best_i) || (after == next_best_i))) {
	return 0;
  } else {
	ZhighCin(RED, C1z.cin);
	if (stepflag) {
	  if (p->box==0) {
		centre_pos = arrp(acedata,p->next, CLONE)->x;
                 /* fred 4/16/03 ctgdisplay(currentctg);*/
                 if(ctg_window!=NULL) refresh_all_track_colors();
	  }
	  /* Highlight best neighbour in Purple */
	  ZhighCin(PURPLE, best_i);
	  /* Highlight second best neighbour in PaleViolet */
	  ZhighCin(PALEVIOLET, next_best_i);
          if(ctg_window!=NULL) refresh_all_track_colors();
	}
  	printf("Clone=%12s Best=%12s   %.0e    NextBest=%12s  %.0e\n", C1z.clone, 
  			arrp(acedata, best_i, CLONE)->clone, best_score,
  			arrp(acedata, next_best_i, CLONE)->clone, next_best_score);
	return 1;
  }

  return 0;
}

/*********************************************************88
                     DEF: CtgStep
************************************************************/
void snCtgStep()
{
  CLONE clone;
  struct contig *p;
  static int ctg=0, cnt=0;

 
  if (!Zall_ok(1, 1)) return;
  if (currentctg!=ctg) Ctgstep = root;
  else if (Ctgstep==NULL) Ctgstep = root;
  ctg = currentctg;
  if (Ctgstep==root) cnt=0;

  for (p=Ctgstep; p!=NULL; p = p->new)
	{
      if (graphInterruptCalled()) {
		printf("User Interrupt - pre-mature termination of CtgCheck\n");
		return;
      } 
	  clone = arr(acedata, p->next, CLONE);
	  if (clone.fp == NULL)  continue;
	  if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
	  if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
	  if (!loadCz(&C1z, p->next)) continue;

	  if (snDoCtgCheck(p, 1)) {
		cnt++;
		sprintf(scoreText,"CtgCheck #%d",cnt); Show; 
		Ctgstep = p->new;
		return;
	  }
	}
  Ctgstep=NULL;
  printf("Stepped through %d CtgCheck\n", cnt);
  sprintf(scoreText,"Stepped through %d CtgCheck",cnt); Show; 
}
/****************************************************************
                      DEF: CtgCheck
****************************************************************/
void snCtgCheck()
{
  CLONE clone;
  int cnt=0;
  struct contig *p;

  if (!Zall_ok(1, 1)) return;
  Ctgstep=NULL;
  clhigh=NULL;    /* cari 6aug04 - highlighted clones do not get highlighted if bad */

  printf("\n>> Check Ctg%i  (Tol %i, Cutoff %.0e)\n", 
  		  currentctg,  Pz.tol, Pz.cutFlt); 
  for (p=root; p!=NULL; p = p->new)
	{
      if (graphInterruptCalled()) {
		printf("User Interrupt - pre-mature termination of CtgCheck\n");
		goto DONE;
      } 
	  clone = arr(acedata, p->next, CLONE);
	  if (clone.fp == NULL)  continue;
	  if (showburied==1 && clone.match[0]!=' ') continue; /* V2.2 */
	  if (showburied==2 && clone.mattype == PSEUDO) continue; /* V2.2 */
	  if (!loadCz(&C1z, p->next)) continue;

	  cnt += snDoCtgCheck(p,0);
	}
 DONE: ;
  sprintf(scoreText,"Contig has %d pair of bad clones",cnt); Show; 
  printf("Contig has %d bad clones\n",cnt);
  if (Zlogfp) fflush(Zlogfp);
  redrawfingerprints();
  if(ctg_window!=NULL) refresh_all_track_colors();
}

